public class solutionDynamicFields {
             
        private PageReference savePage;
       
        
        private List<String> solselectedNames = new List<String> ();
        private List<String> solunSelectedNames = new List<String>();
        
        
        private Set<String> solinaccessibleNames = new Set<String>();
        private Set<String> currentFieldSets = new Set<String>();
        private Set<String> recordTypes = new Set<String>();
        
        public List<String> solselected {get; set; }
        public List<String> solunselected {get; set; }
        
        public String selectedEntity{get;set;}
        public String selectedFieldSet{get;set;}
        public String newFieldSet{get;set;}
        
        
        public String allFieldsList{get;set;}
        private List<CustFieldSets__c> fieldSetsList;
        
        public List<String> displayFields {
                get; 
                private set;
        }
        
       public List<SelectOption> fieldSetSelectOptions { 
                get
                {
                        List<String> sorted = new List<String>(currentFieldSets);                         
                        sorted.sort();
                        List<SelectOption> options = new List<SelectOption>();
                        for (String s : sorted) {
                                options.add(new SelectOption(s, s));
                                }
                        return options;
                }
        }
        
                public List<SelectOption> recordTypeSelectOptions { 
                get
                {
                        List<String> sorted = new List<String>(recordTypes);                         
                        sorted.sort();
                        List<SelectOption> options = new List<SelectOption>();
                        for (String s : sorted) {
                                options.add(new SelectOption(s, s));
                                }
                        return options;
                }
        }
        
        public List<SelectOption> entitySelectOptions { 
                get
                {
                        List<String> sorted = new List<String>(); 
                        sorted.add('Solution__c');
                        sorted.add('SolutionComponent__c');                        
                        sorted.sort();
                        List<SelectOption> options = new List<SelectOption>();
                        for (String s : sorted) {
                                options.add(new SelectOption(s, s));
                                }
                        return options;
                }
        }
       
       public List<SelectOption> solselectedOptions { 
                get
                {
                        List<String> sorted = new List<String>(solselectedNames);
                        List<SelectOption> options = new List<SelectOption>();
                        
                        for (String s : sorted) {
                                options.add(new SelectOption(s, s));
                        }
                        return options;
                }
        }
        
        public List<SelectOption> solunSelectedOptions { 
                get
                {
                        List<String> sorted = new List<String>(solunSelectedNames);
                        sorted.sort();
                        List<SelectOption> options = new List<SelectOption>();
                        for (String s : sorted) {
                                options.add(new SelectOption(s, fixName(s)));
                        }
                        return options;
                }
        }
        
        public solutionDynamicFields () { 
                                selectedEntity ='Solution__c';
                                Initialise();     
                init();
        }        
        
        public PageReference Save() {                        
                UpdateFieldSetList();
                Database.upsert(fieldSetsList);
                return null;
        }
        
        public void NewFieldSet(){
                CustFieldSets__c newfs = new CustFieldSets__c();
                newfs.Entity__c = selectedEntity;
                newfs.FieldSet__c = newFieldSet;
                fieldSetsList.add(newfs);
                
                UpdateFieldSetsDropDown();
                selectedFieldSet = newFieldSet;
                init();
                
        }
        
        public void updateFields(){
                        
                        init();
        }
        public void Initialise(){
                        UpdateRecordTypesDropDown();
                        fieldSetsList = [SELECT Id, Entity__c, FieldSet__c, SelectedFields__c FROM CustFieldSets__c];

        }
        
        private void UpdateFieldSetsDropDown(){
               //List<CustFieldSets__c > entfSets = [SELECT Id, Entity__c, FieldSet__c, SelectedFields__c FROM CustFieldSets__c WHERE Entity__c =: selectedEntity];
               currentFieldSets.clear();
                for(CustFieldSets__c fsetEntry : fieldSetsList)
                {
                        if(fsetEntry.Entity__c == selectedEntity){
                                currentFieldSets.add(fsetEntry.FieldSet__c);
                                if(selectedFieldSet == null || selectedFieldSet =='')
                                {
                                        selectedFieldSet = fsetEntry.FieldSet__c;
                                }
                        }
                }
        }
        private void UpdateRecordTypesDropDown(){
                        Schema.DescribeSObjectResult R = Solution__c.SObjectType.getDescribe();
                        Map<ID,Schema.RecordTypeInfo> recTypesMap = R.getRecordTypeInfosByID();
                                for(ID rectypId: recTypesMap.keySet()){
                                        Schema.RecordTypeInfo recTypeInst = recTypesMap.get(rectypId);         
                                        String RecType = recTypeInst.getName();
                                        recordTypes.add(RecType) ;
                                } 
        }
        
        private void UpdateFieldSetList(){
                                for(CustFieldSets__c fsetEntry : fieldSetsList)
                {
                        if(fsetEntry.Entity__c == selectedEntity && fsetEntry.FieldSet__c == selectedFieldSet){
                                fsetEntry.SelectedFields__c = GetSelectedFieldsList();
                        }
                }
        }
        
        private void UpdateSelecteFieldsFromFieldSetList(){
                                for(CustFieldSets__c fsetEntry : fieldSetsList)
                {
                        System.debug('Entity Retrieved' +fsetEntry.Entity__c+ fsetEntry.FieldSet__c+fsetEntry.SelectedFields__c);
                        System.debug('Entity Retrieved' +fsetEntry.Entity__c+ fsetEntry.FieldSet__c+fsetEntry.SelectedFields__c);
                        
                        if(fsetEntry.Entity__c == selectedEntity && fsetEntry.FieldSet__c == selectedFieldSet){
                                String selFieldString = fsetEntry.SelectedFields__c;
                                
                                if(selFieldString !=null  && selFieldString !=''  )
                                {
                                        String[] selFields = selFieldString.Split(',');
                                        solselected = new List<String>(selFields);
                                        dosolSelect();
                                        
                                        System.debug('Split Fields Array Value: ' +selFieldString);
                                        for(string val :selFields )
                                        {
                                                System.debug('Split Fields Array Count: ' +val);
                                        }
                                }
                        }
                }
        }
        
        private String GetSelectedFieldsList(){
                String concatVal ='';
                for(string fld :solselectedNames)
                {
                        if(concatVal =='')
                        { 
                                concatVal += fld;
                        }
                        else
                        {
                                concatVal += ',' + fld; 
                        }
                }
                return concatVal;
                
        }        
                
        // The methods below are for constructing the select list
        private void init() {
                
                                UpdateFieldSetsDropDown();
                
                Map<String, Schema.SobjectField> fields;                
                System.debug('Selected Entity Value: ' + selectedEntity);
                
                if(selectedEntity == 'Solution__c'){
                        fields = Schema.SobjectType.Solution__c.fields.getMap();
                }
                else if(selectedEntity == 'SolutionComponent__c'){
                        fields = Schema.SobjectType.SolutionComponent__c.fields.getMap();
                }
                
                if(selectedEntity != '')
                {
                        solunSelectedNames.clear();
                        solselectedNames.clear();
                        solinaccessibleNames.clear();
                        for (String s : fields.keySet()) {
                                allFieldsList += s + ',';      
                                                        solunSelectedNames.add(s);
                                } 
                                
                                
                }
                UpdateSelecteFieldsFromFieldSetList();
                
        }
        

        
        private String fixName(String s) {
                return solinaccessibleNames.contains(s) ? '*' + s : s;
        }
        
        public void dosolSelect() {
                for (String s: solselected) {
                        solselectedNames.add(s);
                        Integer i =0;
                        for(string selnm:solunSelectedNames)
                        {
                                if(selnm == s)
                                {
                                        break;  
                                }
                                i++;
                        }
                        solunSelectedNames.remove(i);
                }
        }
        
        public void dosolUnSelect() {
                for (String s: solunselected) {
                        solunSelectedNames.add(s);
                        Integer i =0;
                                                for(string selnm:solselectedNames)
                        {
                                if(selnm == s)
                                {
                                        break;
                                }
                                i++;
                        }
                        solselectedNames.remove(i);
                }
        } 
		public void dosolUp() {
                for (String s: solunselected) {
                	Integer i =0;
                	Integer curIdxNum = -1;
					
					for(string selnm:solselectedNames)
                    {
                        	if(selnm == s)
                        	{
                        		curIdxNum = i;
                        		break;
                        	}
                        	i++;
                    }
                    System.debug('Current Index Number: ' +curIdxNum );
                    
                    if(curIdxNum > 0)
                    {
                    	String prevRecord = solselectedNames[curIdxNum-1];
                    	solselectedNames.set(curIdxNum-1, s);
                    	solselectedNames.set(curIdxNum, prevRecord);
                    }
                }
        }
        
		public void dosolDown() {
                for (String s: solunselected) {
                	Integer i =0;
                	Integer curIdxNum = -1;
					
					for(string selnm:solselectedNames)
                    {
                        	if(selnm == s)
                        	{
                        		curIdxNum = i;
                        		break;
                        	}
                        	i++;
                    }
                    System.debug('Current Index Number: ' +curIdxNum );
                    
                    if(curIdxNum > -1 && curIdxNum < solselectedNames.size()-1 )
                    {
                    	String prevRecord = solselectedNames[curIdxNum + 1];
                    	solselectedNames.set(curIdxNum + 1, s);
                    	solselectedNames.set(curIdxNum, prevRecord);
                    }
                }
        }       
}